/* Vecmath.

   Copyright (C) 2001, 2002, 2003 Stefan Maierhofer.

   Written by Stefan Maierhofer <sm@cg.tuwien.ac.at>

   This file is part of Vecmath.

   Vecmath is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   Vecmath is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with Vecmath; if not, write to the Free Software Foundation,
   Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */

using System;

namespace Vecmath
{

    /// <summary>
    /// Pnt2F.
    /// </summary>
    public struct Pnt2F
    {

        public static Pnt2F Identity = new Pnt2F(0,0);

        public Pnt2F(float xy)
        {
            _x = new float[2];
            _x[0] = xy; _x[1] = xy;
        }

        public Pnt2F(float x, float y)
        {
            _x = new float[2];
            _x[0] = x; _x[1] = y;
        }

        public Pnt2F(ref float [] x)
        {
            _x = new float[2];
            _x[0] = x[0]; _x[1] = x[1];
        }

        public float this [int index]
        {
            get { return _x[index]; }
            set { _x[index] = value; }
        }

        public float x
        {
            get { return _x[0]; }
            set { _x[0] = value; }
        }

        public float y
        {
            get { return _x[1]; }
            set { _x[1] = value; }
        }

        public static explicit operator Pnt2F(Pnt2D v)
        {
            return new Pnt2F((float)v.x, (float)v.y);
        }

        public static explicit operator Pnt2F(Vec2F v)
        {
            return new Pnt2F(v.x, v.y);
        }

        public static Pnt2F operator+(Pnt2F v, float f)
        {
            return new Pnt2F(v[0] + f, v[1] + f);
        }

        public static Pnt2F operator+(Pnt2F v, Vec2F w)
        {
            return new Pnt2F(v[0] + w[0], v[1] + w[1]);
        }

        public static Pnt2F operator-(Pnt2F v)
        {
            return new Pnt2F(-v[0], -v[1]);
        }

        public static Pnt2F operator-(Pnt2F v, float f)
        {
            return new Pnt2F(v[0] - f, v[1] - f);
        }

        public static Vec2F operator-(Pnt2F v, Pnt2F w)
        {
            return new Vec2F(v[0] - w[0], v[1] - w[1]);
        }

        public static Pnt2F operator*(Pnt2F v, float f)
        {
            return new Pnt2F(v[0] * f, v[1] * f);
        }

        public static Pnt2F operator/(Pnt2F v, float f)
        {
            return new Pnt2F(v[0] / f, v[1] / f);
        }

        public int MinDim
        {
            get
            {
                return (_x[0] < _x[1]) ? 0 : 1;
            }
        }

        public int MaxDim
        {
            get
            {
                return (_x[0] > _x[1]) ? 0 : 1;
            }
        }

        public float Minimum
        {
            get
            {
                return (_x[0] < _x[1]) ? _x[0] : _x[1];
            }
        }

        public float Maximum
        {
            get
            {
                return (_x[0] > _x[1]) ? _x[0] : _x[1];
            }
        }

        public static bool operator<(Pnt2F a, Pnt2F b)
        {
            return (
                a._x[0] < b._x[0] &&
                a._x[1] < b._x[1]
                );
        }

        public static bool operator<=(Pnt2F a, Pnt2F b)
        {
            return (
                a._x[0] <= b._x[0] &&
                a._x[1] <= b._x[1]
                );
        }

        public static bool operator==(Pnt2F a, Pnt2F b)
        {
            return (
                a._x[0] == b._x[0] &&
                a._x[1] == b._x[1]
                );
        }

        public static bool operator!=(Pnt2F a, Pnt2F b)
        {
            return (
                a._x[0] != b._x[0] ||
                a._x[1] != b._x[1]
                );
        }

        public static bool operator>=(Pnt2F a, Pnt2F b)
        {
            return (
                a._x[0] >= b._x[0] &&
                a._x[1] >= b._x[1]
                );
        }

        public static bool operator>(Pnt2F a, Pnt2F b)
        {
            return (
                a._x[0] > b._x[0] &&
                a._x[1] > b._x[1]
                );
        }

        public static Pnt2F Min(Pnt2F a, Pnt2F b)
        {
            return new Pnt2F(
                Math.Min(a._x[0], b._x[0]),
                Math.Min(a._x[1], b._x[1])
                );
        }

        public static Pnt2F Max(Pnt2F a, Pnt2F b)
        {
            return new Pnt2F(
                Math.Max(a._x[0], b._x[0]),
                Math.Max(a._x[1], b._x[1])
                );
        }

        internal float [] _x;

        public override bool Equals(object obj)
        {
            Pnt2F x = (Pnt2F)obj;
            return (
                _x[0] == x._x[0] &&
                _x[1] == x._x[1]
                );
        }

        public override int GetHashCode()
        {
            return base.GetHashCode ();
        }

        public override string ToString()
        {
            return "Pnt2F(" + _x[0] + ", " + _x[1] + ")";
        }

    }

}
